package timer

import "sync"

const (
	// 时间轮槽位总数
	Slot_Max = 1000
)

// 时间轮结构体
type timingWheel struct {
	mu sync.Mutex

	// 当前槽位索引
	index uint64

	// 槽位列表
	slots [Slot_Max]*taskList
}

// 添加定时任务
func (tw *timingWheel) AddTask(duration, expireTime uint64, task *task) {
	tw.mu.Lock()
	index := (tw.index + duration) % Slot_Max
	tw.mu.Unlock()

	tw.slots[index].Add(expireTime, task)
}

// 转动指定数量的槽位
func (tw *timingWheel) Turn(startTime, stopTime uint64, tasks *[]*task) {
	var index uint64
	for currTime := startTime + 1; currTime <= stopTime; currTime++ {
		tw.mu.Lock()
		tw.index = (tw.index + 1) % Slot_Max
		index = tw.index
		tw.mu.Unlock()

		tw.slots[index].Expire(currTime, tasks)
	}
}

// 清理时间轮
func (tw *timingWheel) Clear() {
	tw.index = 0
	tasks := make([]*task, 0)
	for _, slot := range tw.slots {
		slot.Clear(&tasks)
	}
	for _, task := range tasks {
		releaseTask(task)
	}
}

// 新建一个时间轮
func newTimingWheel() *timingWheel {
	tw := new(timingWheel)
	for i := 0; i < Slot_Max; i++ {
		tw.slots[i] = &taskList{}
	}
	return tw
}
